;__DWCON09_________________________________________________________________________________________
;
;	Z80 I/O CONTROLLER CODE FOR THE 6809 PROCESSOR
;
;	WRITTEN BY: DAN WERNER -- 11/14/2009
;__________________________________________________________________________________________________
;
;	Supported Function Calls
;
;	00H	
;	01H	Return Keyboard Character
;	02H	Display Console Character
;	03H	HOME DRIVE HEAD
;	04H	READ 512 BYTE SECTOR
;	05H	WRITE 512 BTYE SECTOR
;	06H	READ BUFFER BYTE
;	07H	WRITE BUFFER BYTE
;
;
;	F0H	SEND CUBIX SYSTEM FILE
;
;__________________________________________________________________________________________________
;
; CONFIGURATION
;__________________________________________________________________________________________________
;
;
USEFLOPPYA	.EQU	01		; NONZERO = USE FLOPPY FOR DRIVE "A"
USEATAPIB	.EQU	01		; NONZERO = USE ATAPI ZIP DRIVE (IDE SECOND) FOR DRIVE "B"
USEIDEC		.EQU	01		; NONZERO = USE IDE HDD (IDE PRIM) FOR DRIVE "C"
IDEOFFSET	.EQU	$50		; SET FOR STARTING OF IDE PARTITION
					; PARTITION SIZE IS $FFFF SECTORS (32MB), AND LBA ADDRESS
					; WILL BE OOXXXX, WHERE OO IS OFFSET AND XXXX ARE SECTORS
					; 0000-FFFF.
USEDSKY		.EQU	01		; NONZERO = USE DSKY DEVICE FOR DISK IO STATUS
				
;
;
;__________________________________________________________________________________________________
;
; DATA CONSTANTS
;__________________________________________________________________________________________________
;REGISTER		IO PORT		; FUNCTION
PPIA		.equ	$00		; 8255 PORT A
PPIB		.equ	$01		; 8255 PORT B
PPIC		.equ	$02		; 8255 PORT C
PPICONT		.equ	$03		; 8255 CONTROL PORT 

BDOS		.equ	$0005		; BDOS ENTRY

; IDE REGISTER		IO PORT		; FUNCTION
IDELO:		 .EQU 	20H		; DATA PORT (LOW BYTE)
IDEERR:		 .EQU 	21H		; READ: ERROR REGISTER; WRITE: PRECOMP
IDESECTC:	 .EQU 	22H		; SECTOR COUNT
IDESECTN:	 .EQU 	23H		; SECTOR NUMBER
IDECYLLO:	 .EQU 	24H		; CYLINDER LOW
IDECYLHI:	 .EQU 	25H		; CYLINDER HIGH
IDEHEAD:	 .EQU 	26H		; DRIVE/HEAD
IDESTTS:	 .EQU 	27H		; READ: STATUS; WRITE: COMMAND
IDEHI:		 .EQU 	28H		; DATA PORT (HIGH BYTE)
IDECTRL:	 .EQU 	2EH		; READ: ALTERNATIVE STATUS; WRITE; DEVICE CONTROL
IDEADDR:	 .EQU 	2FH		; DRIVE ADDRESS (READ ONLY)
FMSR:		 .EQU	036H		; ADDRESS OF MAIN STATUS REGISTER
FDATA:		 .EQU	037H		; FLOPPY DATA REGISTER
FLATCH:		 .EQU	03AH		; FLOPPY CONFIGURATION LATCH
FDMA:		 .EQU	03CH		; PSEUDO DMA ADDRESS
;
; FDC CONFIGURATION LATCH OUTPUT BIT PATTERNS
MOTOR:		 .EQU	00000000b	; BIT PATTERN IN LATCH FOR MOTOR CONTROL (ON)
TERMCN:		 .EQU	00000001b	; BIT PATTERN IN LATCH TO WRITE A TC STROBE
RESETL:		 .EQU	00000010b	; BIT PATTERN IN LATCH TO RESET ALL BITS
MINI:		 .EQU	00000100b	; BIT PATTERN IN LATCH TO SET MINI MODE FDC9229 LOW DENS=1, HIGH DENS=0
PRECOMP:	 .EQU	00100000b	; BIT PATTERN IN LATCH TO SET WRITE PRECOMP 125 NS:
FDDENSITY:	 .EQU	01000000b	; BIT PATTERN IN LATCH TO FLOPPY LOW DENSITY (HIGH IS 0)
FDREADY:	 .EQU	10000000b	; BIT PATTERN IN LATCH TO FLOPPY READY (P-34):



	.org	$0100

;__________________________________________________________________________________________________
;
; 	INITIALIZE
;__________________________________________________________________________________________________
	
	.IF USEFLOPPYA 
	CALL	SETUPDRIVE		; SETUP THE FLOPPY INTERFACE
	.ENDIF

	LD	A,$AE			; INITIALIZE 8255
					; 1 01 0 1 1 1 0
					; |  | | | | | |  
					; |  | | | | | Port C Lower output
					; |  | | | | Port B Input
					; |  | | | Mode 1, Strobed I/0
					; |  | | Port C upper, Input
					; |  | Port A Output
					; |  Mode 1, Strobed I/0
					; Active, set control Word
					;
	OUT	(PPICONT),A		; 
	
	LD	HL,(0001H)		; GET WBOOT ADDRESS
	LD	BC,1603H		; GET CP/M TOP
	SBC	HL,BC			;
	LD	(CPMSTART),HL		; SET IT
	DEC	HL			;
	LD	SP,HL			; SETUP STACK


;__________________________________________________________________________________________________
;
; 	MAIN LOOP
;__________________________________________________________________________________________________
MAIN:
	CALL	ECB_CHARIN		; GET ECB DATA

	CP	$01			; IS RETURN KB CHAR
	JP	Z,F_KBIN		; YES, DO IT
	
	CP	$02			; IS DISPLAY CONSOLE CHAR
	JP	Z,F_CONOUT		; YES, DO IT
	
	CP	$03			; IS HOME DRIVE HEAD
	JP	Z,F_HOME		; YES, DO IT
	
	CP	$04			; IS READ SECTOR
	JP	Z,F_READSEC		; YES, DO IT
	
	CP	$05			; IS WRITE SECTOR
	JP	Z,F_WRITESEC		; YES, DO IT

	CP	$06			; IS READ BUFFER BYTE
	JP	Z,F_READBUFBYTE		; YES DO IT

	CP	$07			; IS WRITE BUFFER BYTE			
	JP	Z,F_WRITEBUFBYTE	; YES, DO IT

	CP	$F0			; IS SEND CUBIX?			
	JP	Z,F_SENDCUBIX		; YES, DO IT

		
	JP	MAIN			; LOOP, UNKNOWN CMD
	
;__F_KBIN___________________________________________________________________________________________ 
;
;	PERFORM FUNCTION: GET A BYTE FROM KB
;___________________________________________________________________________________________________
;
F_KBIN:
	LD	E,$FF			; BDOS DIRECT CONSOLE IN/OUT 
	LD	C,$06			; FUNCTION
	CALL	BDOS			;
	CALL	ECB_CHAROUT		; SEND DATA
	JP	MAIN


;__F_CONOUT_________________________________________________________________________________________ 
;
;	PERFORM FUNCTION: DISPLAY A BYTE ON THE CONSOLE
;___________________________________________________________________________________________________
;
F_CONOUT:
	CALL	ECB_CHARIN		; GET ECB DATA
	LD	E,A			; PUT DATA IN E
	LD	C,$02			; BDOS CONSOLE OUTPUT FUNCTION
	CALL	BDOS			; SEND CHARACTER TO OUTPUT
	JP	MAIN			; GO TO MAIN LOOP

;__F_HOME___________________________________________________________________________________________ 
;
;	PERFORM FUNCTION: HOME THE DRIVE HEAD
;___________________________________________________________________________________________________
;
F_HOME:
	CALL	ECB_DEC_CHARIN		; GET ECB DATA (DRIVE NO)
	LD	(DRIVE),A		;
					;
	LD	A,(DRIVE)		;

	.IF USEFLOPPYA 	
	CP	00H			; DRIVE 0?
	JP	Z,HOME_0		; YUP, DO IT
	.ENDIF

;	CP	01H			; DRIVE 1?
;	JP	Z,HOME_1		; YUP, DO IT

;	CP	02H			; DRIVE 2?
;	JP	Z,HOME_2		; YUP, DO IT

;	CP	03H			; DRIVE 3?
;	JP	Z,HOME_3		; YUP, DO IT
	
	JP	MAIN			; GO TO MAIN LOOP
	

;__F_READSEC________________________________________________________________________________________ 
;
;	PERFORM FUNCTION: READ A SECTOR
;___________________________________________________________________________________________________
;
F_READSEC:
	CALL	ECB_DEC_CHARIN		; GET ECB DATA (DRIVE NO)
	LD	(DRIVE),A		;
	CALL	ECB_DEC_CHARIN		; GET HEAD#
	LD	(HEAD),A		; STORE IT
	CALL	ECB_DEC_CHARIN		; GET TRACK#
	LD	(TRACK),A		; STORE IT
	CALL	ECB_DEC_CHARIN		; GET SECTOR#
	LD	(SECTOR),A		; STORE IT
					;
	LD	A,(DRIVE)		;
	
	.IF USEFLOPPYA 
	CP	00H			; DRIVE 0?
	JP	Z,READ_0		; YUP, DO IT
	.ENDIF

	.IF USEATAPIB
	CP	01H			; DRIVE 1?
	JP	Z,READ_1		; YUP, DO IT
	.ENDIF

	.IF USEIDEC
	CP	02H			; DRIVE 2?
	JP	Z,READ_2		; YUP, DO IT
	.ENDIF

;	CP	03H			; DRIVE 3?
;	JP	Z,READ_3		; YUP, DO IT
	
	LD	A,0FFH			; SIGNAL ERROR
	CALL	ECB_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP
	
	
;__F_WRITESEC_______________________________________________________________________________________ 
;
;	PERFORM FUNCTION: WRITE A SECTOR
;___________________________________________________________________________________________________
;
F_WRITESEC:
	CALL	ECB_DEC_CHARIN		; GET ECB DATA (DRIVE NO)
	LD	(DRIVE),A		;
	CALL	ECB_DEC_CHARIN		; GET HEAD#
	LD	(HEAD),A		; STORE IT
	CALL	ECB_DEC_CHARIN		; GET TRACK#
	LD	(TRACK),A		; STORE IT
	CALL	ECB_DEC_CHARIN		; GET SECTOR#
	LD	(SECTOR),A		; STORE IT
					;
	LD	A,(DRIVE)		;
	
	.IF	USEFLOPPYA
	CP	00H			; DRIVE 0?
	JP	Z,WRITE_0		; YUP, DO IT
	.ENDIF

	.IF 	USEATAPIB
	CP	01H			; DRIVE 1?
	JP	Z,WRITE_1		; YUP, DO IT
	.ENDIF

	.IF	USEIDEC
	CP	02H			; DRIVE 2?
	JP	Z,WRITE_2		; YUP, DO IT
	.ENDIF

;	CP	03H			; DRIVE 3?
;	JP	Z,WRITE_3		; YUP, DO IT
	
	LD	A,0FFH			; SIGNAL ERROR
	CALL	ECB_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP
	
;__F_SENDCUBIX________________________________________________________________________________________ 	
;
;	SEND CUBIX IMAGE
;___________________________________________________________________________________________________
;	
F_SENDCUBIX:
	LD	DE,LOADING_MESSAGE	;
	LD	C,09H			; CP/M WRITE START STRING TO CONSOLE CALL
	CALL	0005H			;
	CALL	CRLF			;
	LD	DE,CUBIXFCB		; SETUP THE FCB
	LD	C,0FH			; READ SEQUENTIAL	
	CALL	BDOS			; 
	CP	0FFH			;
	JP	Z,F_SENDCUBIX_3		;
	LD	HL,SECTOR_BUFFER	;	
	PUSH	HL			;
F_SENDCUBIX_1:
	POP	DE			;
	PUSH	DE			;
	LD	C,01AH			;
	CALL	BDOS			; SET DMA ADDRESS
	LD	DE,CUBIXFCB		; SETUP THE FCB
	LD	C,014H			; READ SEQUENTIAL	
	CALL	BDOS			; 
	OR	A			;
	JP	NZ,F_SENDCUBIX_2	;
	LD	BC,0080H		;
	POP	HL			;	
	ADD	HL,BC			;
	PUSH	HL			;
	JP	F_SENDCUBIX_1		;
F_SENDCUBIX_2:				;
	POP	HL			;
	LD	DE,CUBIXFCB		; SETUP THE FCB
	LD	C,10H			; CLOSE FILE
	CALL	BDOS			; 
	CALL	CRLF			;	
	LD	A,00H			; SIGNAL SUCCESS
	CALL	ECB_ENC_CHAROUT		; SEND STATUS		
	JP	MAIN			; GO TO MAIN LOOP
F_SENDCUBIX_3:		
	LD	DE,ERROR_MESSAGE	;
	LD	C,09H			; CP/M WRITE START STRING TO CONSOLE CALL
	CALL	0005H			;
	CALL	CRLF			;	
	LD	A,0FFH			; SIGNAL ERROR
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP	

CUBIXFCB:
	.DB	00
	.TEXT	"CUBIXIMG"
	.TEXT	"BIN"
	.DB	00
	.DB	00
	.DB	00
	.DB	00
	.DB	00,00,00,00,00,00,00
	.DB	00,00,00,00,00,00,00
	.DB	00,00,00
	
LOADING_MESSAGE:
.TEXT	"CUBIX LOADING . . . $"
ERROR_MESSAGE:
.TEXT	"LOAD ERROR$"		
	
		
	
;__HOME_0___________________________________________________________________________________________ 	
;
;	HOME DRIVE 0 TO TRACK 0
;___________________________________________________________________________________________________
;
HOME_0:
	LD	A,0			;
	LD	(TRACK),A		;
	CALL	SETTRACK		;
	CALL	SETTRACK		;
	JP	MAIN			; GO TO MAIN LOOP

	
	
;__READ_0___________________________________________________________________________________________ 
;
;	READ A SECTOR FROM DRIVE 0
;___________________________________________________________________________________________________
;
READ_0:
	CALL	SETTRACK		;
	CALL	FLOPPYREAD		;		
	LD	A,(ST0)			; GET STATUS FLAG 0
	AND	0F8H			; MASK OF DRIVE AND HEAD SELECTION
	LD	B,A			; MOVE STATUS FLAG 0 TO B
	LD	A,(ST1)			; GET STATUS FLAG 1
	OR	B			; IF ZERO READ WAS OK
	JP	NZ,READ_0_ERROR		;

	LD	A,00H			; SIGNAL SUCCESS
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP
READ_0_ERROR:				;
	LD	A,0FFH			; SIGNAL ERROR
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP

	
	
	
	
	
	
;__READ_1___________________________________________________________________________________________ 
;
;	READ A SECTOR FROM DRIVE 1
;___________________________________________________________________________________________________
;
READ_1:
	LD	A,10H			; SET TO SECONDARY DEVICE
	LD	(IDEDEVICE),A		;
					;
	LD	A,(SECTOR)		;
	LD	(LBA_TARGET_LO),A 	; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ
	LD	A,(TRACK)		;
	LD	(LBA_TARGET_LO+1),A	; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ
	LD	A,(HEAD)		;
	LD	(LBA_TARGET_HI),A 	; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ
	LD	A,00H			;
	LD	(LBA_TARGET_HI+1),A	; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ
					;
	CALL	ATAPI_READ_SECTOR	; READ THE IDE HARD DISK SECTOR
	JP	NC,READ_1_ERROR		;
	LD	A,00H			; SIGNAL SUCCESS
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP
READ_1_ERROR:				;
	LD	A,0FFH			; SIGNAL ERROR
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP

;__READ_2___________________________________________________________________________________________ 
;
;	READ A SECTOR FROM DRIVE 2
;___________________________________________________________________________________________________
;
READ_2:
					;
	LD	A,(SECTOR)		;
	LD	(LBA_TARGET_LO),A 	; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ
	LD	A,(TRACK)		;
	LD	(LBA_TARGET_LO+1),A	; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ
	LD	A,(HEAD)		;
	
	ADD	A,IDEOFFSET		; OFFSET CP/M PARTITION

	LD	(LBA_TARGET_HI),A 	; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ
	LD	A,00H			;
	LD	(LBA_TARGET_HI+1),A	; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ
					;
	CALL	IDE_READ_SECTOR		; READ THE IDE HARD DISK SECTOR
	JP	NC,READ_2_ERROR		;
	LD	A,00H			; SIGNAL SUCCESS
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP
READ_2_ERROR:				;
	LD	A,0FFH			; SIGNAL ERROR
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP

	
;__WRITE_0__________________________________________________________________________________________ 
;
;	WRITE A SECTOR TO DRIVE 0
;___________________________________________________________________________________________________
;
WRITE_0:
	CALL	SETTRACK		;
	CALL	FLOPPYWRITE		;
		
	LD	A,(ST0)			; GET STATUS FLAG 0
	AND	0F8H			; MASK OF DRIVE AND HEAD SELECTION
	LD	B,A			; MOVE STATUS FLAG 0 TO B
	LD	A,(ST1)			; GET STATUS FLAG 1
	OR	B			; IF ZERO READ WAS OK
	JP	NZ,WRITE_0_ERROR	;

	LD	A,00H			; SIGNAL SUCCESS
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP

WRITE_0_ERROR:				;
	LD	A,0FFH			; SIGNAL ERROR
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP

	RET

	
	
;__WRITE_1__________________________________________________________________________________________ 
;
;	WRITE A SECTOR TO DRIVE 1
;___________________________________________________________________________________________________
;
WRITE_1:
	LD	A,10H			; SET TO SECONDARY DEVICE
	LD	(IDEDEVICE),A		;
					;
	LD	A,(SECTOR)		;
	LD	(LBA_TARGET_LO),A 	; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ
	LD	A,(TRACK)		;
	LD	(LBA_TARGET_LO+1),A	; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ
	LD	A,(HEAD)		;
	LD	(LBA_TARGET_HI),A 	; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ
	LD	A,00H			;
	LD	(LBA_TARGET_HI+1),A	; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ
						
	CALL	ATAPI_WRITE_SECTOR	; WRITE THE IDE HARD DISK SECTOR
	JP	NC,WRITE_1_ERROR	;
	LD	A,00H			; SIGNAL SUCCESS
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP

WRITE_1_ERROR:				;
	LD	A,0FFH			; SIGNAL ERROR
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP

	RET
	

;__WRITE_2__________________________________________________________________________________________ 
;
;	WRITE A SECTOR TO DRIVE 2
;___________________________________________________________________________________________________
;
WRITE_2:
					;
	LD	A,(SECTOR)		;
	LD	(LBA_TARGET_LO),A 	; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ
	LD	A,(TRACK)		;
	LD	(LBA_TARGET_LO+1),A	; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ
	LD	A,(HEAD)		;
	
	ADD	A,IDEOFFSET		; OFFSET CP/M PARTITION
	
	LD	(LBA_TARGET_HI),A 	; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ
	LD	A,00H			;
	LD	(LBA_TARGET_HI+1),A	; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ
						
	CALL	IDE_WRITE_SECTOR	; WRITE THE IDE HARD DISK SECTOR
	JP	NC,WRITE_2_ERROR	;
	LD	A,00H			; SIGNAL SUCCESS
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP

WRITE_2_ERROR:				;
	LD	A,0FFH			; SIGNAL ERROR
	CALL	ECB_ENC_CHAROUT		; SEND STATUS
	JP	MAIN			; GO TO MAIN LOOP

	RET
	
	
	
	
		
;__F_READBUFBYTE____________________________________________________________________________________ 
;
;	READ A BYTE FROM THE DATA BUFFER
;___________________________________________________________________________________________________
;	
F_READBUFBYTE:
	CALL	ECB_DEC_CHARIN		; GET GET HIGH BYTE OFFSET
	LD	B,A			; STORE IT
	CALL	ECB_DEC_CHARIN		; GET LOW BYTE OFFSET
	LD	C,A			; STORE IT
	LD	HL,SECTOR_BUFFER	;
	ADD	HL,BC			; ADD OFFSET TO BUFFER
	LD	A,(HL)			; GET BYTE
	CALL	ECB_ENC_CHAROUT		; SEND IT
	JP	MAIN			; GO TO MAIN LOOP

	
;__F_WRITEBUFBYTE___________________________________________________________________________________ 
;
;	WRITE A BYTE TO THE DATA BUFFER
;___________________________________________________________________________________________________
;	
F_WRITEBUFBYTE:
	CALL	ECB_DEC_CHARIN		; GET GET HIGH BYTE OFFSET
	LD	B,A			; STORE IT
	CALL	ECB_DEC_CHARIN		; GET LOW BYTE OFFSET
	LD	C,A			; STORE IT
	LD	HL,SECTOR_BUFFER	;
	ADD	HL,BC			; ADD OFFSET TO BUFFER
	CALL	ECB_DEC_CHARIN		; GET BYTE
	LD	(HL),A			; STORE IT
	JP	MAIN			; GO TO MAIN LOOP
	
	
	
;____________________________________________________________________________________________________	
;	
;	
;	
;	
;	
;____________________________________________________________________________________________________	
	
			
;__ECB_CHAROUT_______________________________________________________________________________________ 
;
;	SEND A BYTE TO THE M6809
;	A= BYTE TO SEND
;____________________________________________________________________________________________________
;
ECB_ENC_CHAROUT:			; OUTPUT IS SAME ENCODED OR DECODED
ECB_CHAROUT:
	OUT	(PPIA),A		; SEND TO 8255
	PUSH	AF			; STORE A
	LD	A,$0F			;
	OUT	(PPICONT),A		; RESET 8255 OUTPUT STROBE LINE
ECB_CHAROUT_LOOP:
	IN	A,(PPIC)		;
	AND	%01000000		;
	JP	NZ,ECB_CHAROUT_LOOP	;	
	LD	A,$0E			;
	OUT	(PPICONT),A		; RESET 8255 OUTPUT STROBE LINE
	POP	AF			; RESTORE A
	RET				;



;__ECB_CHARIN_________________________________________________________________________________________ 
;
;	GET A BYTE FROM THE M6809
;	A= RETURNED BYTE
;
;	NOTE THAT NULL CANNOT BE RECVD FROM THE M6809
;_____________________________________________________________________________________________________
;
ECB_CHARIN:
	IN	A,(PPIB)		; RESET 8255 PC1/6821 CB1 WITH RISING EDGE /RD ??
ECB_CHARIN_LOOP:			;
	IN	A,(PPIC)		; CHECK IF DATA WAITING
	AND	$02			; MASK ALL BUT PC1/CB1, IF HIGH DATA WAITING
	JP	Z,ECB_CHARIN_LOOP	; IF NO DATA, LOOP
	IN	A,(PPIB)		; GET DATA
	JP	Z,ECB_CHARIN		; IF NO DATA, LOOP
	RET

;__ECB_DEC_CHARIN_____________________________________________________________________________________ 
;
;	GET A DECODED BYTE FROM THE M6809
;	A= RETURNED BYTE
;
;	THIS WILL RETURN ALL BYTES
;_____________________________________________________________________________________________________
;
ECB_DEC_CHARIN:
	CALL	ECB_CHARIN		; GET BYTE
	CP	27			; IS ESCAPE?
	JP	NZ,ECB_DEC_CHARIN_DONE	; NO, EXIT
	CALL	ECB_CHARIN		; YES, GET NEXT BYTE
	CP 	'0'			; IS NULL CODE?
	JP	Z,ECB_DEC_CHARIN_NULL	; YUP, HANDLE IT
	LD	A,27			; NO, RETURN ESC CODE
	RET				;
ECB_DEC_CHARIN_NULL:			;
	LD	A,0			;
ECB_DEC_CHARIN_DONE:			;
	RET				;


	
	
		
;___IDE_READ_SECTOR______________________________________________________________________________________
;
;	READ IDE SECTOR
;________________________________________________________________________________________________________			
IDE_READ_SECTOR:
	CALL	IDE_WAIT_BUSY_READY 	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	CALL	IDE_SETUP_LBA		; TELL DRIVE WHAT SECTOR IS REQUIRED
	LD	A,20H			;
	OUT	(IDESTTS),A		; 020h = IDE 'READ SECTOR' COMMAND 
IDE_SREX:				;
	CALL	IDE_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	CALL	IDE_TEST_ERROR		; ENSURE NO ERROR WAS REPORTED
	RET	NC			; ERROR, RETURN
	CALL	IDE_WAIT_BUFFER		; WAIT FOR FULL BUFFER SIGNAL FROM DRIVE
	RET	NC			; ERROR, RETURN
	CALL	IDE_READ_BUFFER		; GRAB THE 256 WORDS FROM THE BUFFER
	SCF				; CARRY = 1 ON RETURN = OPERATION OK
	SCF				; CARRY = 1 ON RETURN = OPERATION OK
	RET
	
;___IDE_WRITE_SECTOR_____________________________________________________________________________________
;
;	WRITE IDE SECTOR
;________________________________________________________________________________________________________			
IDE_WRITE_SECTOR:
	CALL	IDE_WAIT_BUSY_READY 	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	CALL	IDE_SETUP_LBA		; TELL DRIVE WHAT SECTOR IS REQUIRED
	LD	A,30H			;
	OUT	(IDESTTS),A		; 030h = IDE 'WRITE SECTOR' COMMAND 
	CALL	IDE_WAIT_BUSY_READY	;
	RET	NC			; ERROR, RETURN
	CALL	IDE_TEST_ERROR		; ENSURE NO ERROR WAS REPORTED
	RET	NC			; ERROR, RETURN
	CALL	IDE_WAIT_BUFFER		; WAIT FOR BUFFER READY SIGNAL FROM DRIVE
	RET	NC			; ERROR, RETURN
	CALL	IDE_WRITE_BUFFER 	; SEND 256 WORDS TO DRIVE'S BUFFER
	CALL	IDE_WAIT_BUSY_READY 	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	CALL	IDE_TEST_ERROR		; ENSURE NO ERROR WAS REPORTED
	RET	NC			; ERROR, RETURN
	SCF				; CARRY = 1 ON RETURN = OPERATION OK
	RET		

;___IDE_SOFT_RESET_______________________________________________________________________________________
;
;	RESET IDE CHANNEL
;________________________________________________________________________________________________________			
IDE_SOFT_RESET:
	LD	A,000000110b		; NO INTERRUPTS, RESET DRIVE = 1
	OUT	(IDECTRL),A		;
	LD	A,000000010b		; NO INTERRUPTS, RESET DRIVE = 0
	OUT	(IDECTRL),A		;
	CALL	IDE_WAIT_BUSY_READY	;THIS TAKES A COUPLE OF SECONDS
	RET	

;___ATAPI_WAIT_BUSY_READY________________________________________________________________________________
;
;	WAIT FOR ATAPI CHANNEL TO BE READY
;________________________________________________________________________________________________________			
ATAPI_WAIT_BUSY_READY:
	LD	DE,0			; CLEAR OUT DE
ATAPI_WBSY:				;
	LD	B,0F0H			; SETUP TIMEOUT
ATAPI_DLP:				;
	DJNZ	ATAPI_DLP		; 
	INC	DE			;
	LD	A,D			;
	OR	E			;
	JR	Z,ATAPI_TO		;
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	010000000b		; MASK OFF BUSY BIT
	JR	NZ,ATAPI_WBSY		; WE WANT BUSY(7) TO BE 0 
	SCF				; CARRY 1 = OK
	RET				;
ATAPI_TO:				;
	XOR	A			; CARRY 0 = TIMED OUT
	RET				;
	
;___IDE_WAIT_DRQ_READY___________________________________________________________________________________
;
;	WAIT FOR IDE CHANNEL TO BE READY
;________________________________________________________________________________________________________			
IDE_WAIT_DRQ_READY:
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	000001000b		; MASK OFF RDY BIT
	JR	Z,IDE_WAIT_DRQ_READY	; WE WANT DRQ(3) TO BE 1
	RET

;___IDE_WAIT_DRQ_ZERO____________________________________________________________________________________
;
;	WAIT FOR IDE DRQ TO BE ZERO
;________________________________________________________________________________________________________			
IDE_WAIT_DRQ_ZERO:
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	000001000b		; MASK OFF RDY BIT
	JR	NZ,IDE_WAIT_DRQ_ZERO	; WE WANT DRQ(3) TO BE 0
	RET

;___IDE_WAIT_BUSY_READY___________________________________________________________________________________
;
;	WAIT FOR IDE CHANNEL TO BE READY
;________________________________________________________________________________________________________			
IDE_WAIT_BUSY_READY:
	LD	DE,0			; CLEAR DE
IDE_WBSY:				;
	LD	B,5			; SETUP TIMEOUT
IDE_DLP:				;
	DEC	B			;
	JP	NZ,IDE_DLP		;
	INC	DE			;
	LD	A,D			;
	OR	E			;
	JP	Z,IDE_TO		;
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	011000000b		; MASK OFF BUSY AND RDY BITS
	XOR	001000000b		; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1
	JP	NZ,IDE_WBSY		;
	SCF				; CARRY 1 = OK
	RET
IDE_TO:
	XOR	A			; CARRY 0 = TIMED OUT
	RET
	
;___IDE_TEST_ERROR_______________________________________________________________________________________
;
;	CHECK FOR IDE ERROR CONDITION
;________________________________________________________________________________________________________			
IDE_TEST_ERROR:
	SCF				;
	IN	A,(IDESTTS)		;
	LD	B,A			; 
	AND	000000001b		; TEST ERROR BIT
	SCF				; 
	RET	Z			;
	LD	A,B			; 
	AND	000100000b		;
	SCF				;
	JP	NZ,IDE_ERR		; TEST WRITE ERROR BIT
	IN	A,(IDEERR)		; READ ERROR FLAGS
IDE_ERR:
	OR	A			; CARRY 0 = ERROR
	RET				; IF A = 0, IDE BUSY TIMED OUT

;___IDE_WAIT_BUFFER_______________________________________________________________________________________
;
;	WAIT FOR DATA BUFFER READY
;________________________________________________________________________________________________________			
IDE_WAIT_BUFFER:
	LD	DE,0			;
IDE_WDRQ:				;
	LD	B,5			;
IDE_BLP:				;
	DEC	B			;
	JP	NZ,IDE_BLP		;	
	INC	DE			;
	LD	A,D			;
	OR	E			;
	JP	Z,IDE_TO2		;
	IN	A,(IDESTTS)		; WAIT FOR DRIVE'S 512 BYTE READ BUFFER 
	AND	000001000b		; TO FILL (OR READY TO FILL)
	JP	Z,IDE_WDRQ		;
	SCF				; CARRY 1 = OK
	RET				;
IDE_TO2:				;
	XOR	A			; CARRY 0 = TIMED OUT
	RET				;

;___IDE_READ_BUFFER_______________________________________________________________________________________
;
;	READ IDE BUFFER
;________________________________________________________________________________________________________			
IDE_READ_BUFFER:
	PUSH	HL			;
	LD	HL,SECTOR_BUFFER	;
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
IDEBUFRD:				;
	IN	A,(IDELO)		; LOW BYTE OF WORD FIRST	
	LD	(HL),A			;
	IN	A,(IDEHI)		; THEN HIGH BYTE OF WORD
	INC	HL			;
	LD	(HL),A			;
	INC	HL			;
	DEC	B			;
	JP	NZ,IDEBUFRD		;
	POP	HL			;
	RET

;___IDE_WRITE_BUFFER_______________________________________________________________________________________
;
;	WRITE TO IDE BUFFER
;________________________________________________________________________________________________________			
IDE_WRITE_BUFFER:
	PUSH	HL			;
	LD	HL,SECTOR_BUFFER	;
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
IDEBUFWT:				;
	INC	HL			;
	LD	A,(HL)			;
	DEC	HL			;
	OUT	(IDEHI),A		; SET UP HIGH LATCHED BYTE BEFORE
	LD	A,(HL)			;
	OUT	(IDELO),A		; WRITING WORD WITH WRITE TO LOW BYTE
	INC	HL			;
	INC	HL			;
	DEC	B			;
	JP	NZ,IDEBUFWT		;
	POP	HL			;
	RET		
	
;___IDE_SETUP_LDA________________________________________________________________________________________
;
;	SETUP IDE DRIVE FOR LDA OPERATION
;________________________________________________________________________________________________________			
IDE_SETUP_LBA:
	LD	A,(LBA_TARGET_LO) 	; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ
	LD	(IDE_LBA0),A		;
	LD	A,(LBA_TARGET_LO+1)	; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ
	LD	(IDE_LBA1),A		;
	LD	A,(LBA_TARGET_HI) 	; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ
	LD	(IDE_LBA2),A		;
	LD	A,(LBA_TARGET_HI+1)	; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ
	AND	000001111b		; ONLY LOWER FOUR BITS ARE VALID
	ADD	A,011100000b		; ENABLE LBA BITS 5:7=111 IN IDE_LBA3
	LD	(IDE_LBA3),A		;
					; READ IDE HD SECTOR
	LD	A,1			;
	OUT	(IDESECTC),A		; SET SECTOR COUNT = 1	
					;	
	LD	A,(IDE_LBA0)		;
	OUT	(IDESECTN),A		; SET LBA 0:7
					;
	LD	A,(IDE_LBA1)		;
	OUT	(IDECYLLO),A		; SET LBA 8:15
					;
	LD	A,(IDE_LBA2)		;
	OUT	(IDECYLHI),A		; SET LBA 16:23
					;
	LD	A,(IDE_LBA3)		;
	AND	000001111b		; LOWEST 4 BITS USED ONLY
	OR	011100000b		; TO ENABLE LBA MODE
	OUT	(IDEHEAD),A		; SET LBA 24:27 + BITS 5:7=111
	.IF	USEDSKY
	CALL	IDESEGDISPLAY		;
	.ENDIF
	RET	

;___ATAPI_SOFT_RESET_____________________________________________________________________________________
;
;	RESET ATAPI BUS
;________________________________________________________________________________________________________			
ATAPI_SOFT_RESET:
	LD	A,000001110b		;NO INTERRUPTS, RESET DRIVE = 1
	OUT	(IDECTRL),A		;
	CALL	DELAY24			;
	LD	A,000001010b		;NO INTERRUPTS, RESET DRIVE = 0
	OUT	(IDECTRL),A		;
	CALL	ATAPI_WAIT_BUSY_READY	;
	RET	NC			; ERROR, RETURN
	CALL	ATAPI_DEVICE_SELECTION	;
	CALL	DELAY24			;
	CALL 	REQUEST_SENSE_LOOP	;
	RET

;___REQUEST_SENSE_LOOP____________________________________________________________________________________
;
;	ATAPI_REQUEST SENSE DATA
;_________________________________________________________________________________________________________			
REQUEST_SENSE_LOOP:
	LD	HL,ATAPI_REQUEST_SENSE	;
	CALL	ATAPI_SEND_PACKET	;
	CALL	ATAPI_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
REQUEST_SENSE_LOOP1:			;
	IN	A,(IDELO)		;
	INC	IX			;
	IN	A,(IDEHI)		;
	INC	IX			;
	DJNZ	REQUEST_SENSE_LOOP1	;
	RRD				; DELAY ONLY
	IN	A,(IDESTTS)		;READ ERROR REG
	AND	000000001b		;MASK OFF BIT
	JR	NZ,REQUEST_SENSE_LOOP	;
	RET

;___ATAPI_DEVICE_SELECTION________________________________________________________________________________
;
;	ATAPI DEVICE SELECTION
;_________________________________________________________________________________________________________			
ATAPI_DEVICE_SELECTION:

	LD	A,(IDEDEVICE)		; SELECTS DEVICE
	OR	0A0H			;
	OUT	(IDEHEAD),A		;	
	RET				;



;__ATAPI_READ_SECTOR_____________________________________________________________________________________________________________ 
;  READ ATAPI SECTOR   
;
;   D E H L = SECTOR (DOUBLE WORD) TO READ 
;________________________________________________________________________________________________________________________________ 
ATAPI_READ_SECTOR:
	LD	A,(LBA_TARGET_LO)	; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ
	LD	(READ_DISK_PACKET+5),A	;
	LD	A,(LBA_TARGET_LO+1)	; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ
	LD	(READ_DISK_PACKET+4),A	;
	LD	A,(LBA_TARGET_HI)	; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ
	LD	(READ_DISK_PACKET+3),A	;
	LD	A,(LBA_TARGET_HI+1)	; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ
	LD	(READ_DISK_PACKET+2),A	;
	.IF	USEDSKY
	CALL	ATAPISEGDISPLAY		;
	.ENDIF
	CALL	REQUEST_SENSE_LOOP	; GET ATAPI SENSE CODES TO CLEAR ERRORS
	LD	HL,READ_DISK_PACKET	; SET POINTER TO READ SECTOR PACKET
	CALL	ATAPI_SEND_PACKET	; SEND PACKET COMMAND
	CALL	ATAPI_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
	LD	IX,SECTOR_BUFFER	;
	IN	A,(IDESTTS)		; READ  REG
	AND	000001000b		; MASK OFF BIT
	CP	08H			; IS DATA WAITING?
	JR	NZ,ATAPI_READ_DATA_EXIT	; NO, EXIT
ATAPI_READ_DATA_LOOP:
	IN	A,(IDELO)		;
	LD	(IX+0),A		;
	INC	IX			;
	IN	A,(IDEHI)		;
	LD	(IX+0),A		;
	INC	IX			;
	DJNZ	ATAPI_READ_DATA_LOOP	;
ATAPI_READ_DATA_EXIT:
	SCF				; CARRY = 1 ON RETURN = OPERATION OK
	RET				;



;__ATAPI_WRITE_SECTOR_____________________________________________________________________________________________________________ 
;  WRITE ATAPI SECTOR   
;
;   D E H L = SECTOR (DOUBLE WORD) TO WRITE 
;________________________________________________________________________________________________________________________________ 
ATAPI_WRITE_SECTOR:

	LD	A,(LBA_TARGET_LO)	; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ
	LD	(WRITE_DISK_PACKET+5),A	;
	LD	A,(LBA_TARGET_LO+1)	; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ
	LD	(WRITE_DISK_PACKET+4),A	;
	LD	A,(LBA_TARGET_HI)	; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ
	LD	(WRITE_DISK_PACKET+3),A	;
	LD	A,(LBA_TARGET_HI+1)	; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ
	LD	(WRITE_DISK_PACKET+2),A	;
	.IF	USEDSKY
	CALL	ATAPISEGDISPLAY		;
	.ENDIF
	CALL 	REQUEST_SENSE_LOOP	;
	LD	HL,WRITE_DISK_PACKET	; SET POINTER TO WRITE PACKET COMMAND
	CALL	ATAPI_SEND_PACKET	; SEND THE PACKET COMMAND						
	CALL	ATAPI_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
	LD	IX,SECTOR_BUFFER	;
ATAPI_WRITE_DATA_LOOP:
	IN	A,(IDESTTS)		; READ  REG
	LD	A,(IX+0)		;
	PUSH    AF			;
	INC	IX			;
	LD	A,(IX+0)		;
	OUT	(IDEHI),A		;
	POP	AF			;
	OUT	(IDELO),A		;
	INC	IX			;
	DJNZ	ATAPI_WRITE_DATA_LOOP	;
	SCF				; CARRY = 1 ON RETURN = OPERATION OK
	RET				;




;__ATAPI_SEND_PACKET_____________________________________________________________________________________________________________ 
;  SEND PACKET POINTED TO BY HL TO ATAPI DRIVE   
;
;________________________________________________________________________________________________________________________________ 
ATAPI_SEND_PACKET:

	CALL	ATAPI_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	CALL	IDE_WAIT_DRQ_ZERO	;
					;
	LD	A,0AH			;
	OUT	(IDECTRL),A		; DISABLE INT
	LD	A,00H			;
	OUT	(IDEERR),A		;
	LD	A,00H			;
	OUT	(IDESECTC),A		; 
	LD	A,00H			;
	OUT	(IDESECTN),A		;
	LD	A,00H			;
	OUT	(IDECYLLO),A		; 
	LD	A,60H			;
	OUT	(IDECYLHI),A		; 
	LD	A,(IDEDEVICE)		;
	OUT	(IDEHEAD),A		; BIT 4 SELECTS DEVICE
	LD	A,0A0H			;
	OUT	(IDESTTS),A		;
					;
	CALL	IDE_WAIT_DRQ_READY	; MAKE SURE DRIVE IS READY TO PROCEED
					;
	LD	B,6			; SEND 12 BYTES (6 WORDS)
					;
ATAPI_SEND_PACKET_LOOP:
	LD	A,(HL)			; GET BYTE
	LD	D,A			; STORE LOW BYTE IN D
	INC	HL			; INC POINTER
	LD	A,(HL)			; GET HIGH BYTE
	OUT	(IDEHI),A		; STORE HIGH BYTE
	LD	A,D			; MOVE LOW BYTE INTO A
	OUT	(IDELO),A		; STORE LOW BYTE
	INC	HL			; INC POINTER
	IN	A,(IDECTRL)		; GET STATUS
	DJNZ	ATAPI_SEND_PACKET_LOOP	; LOOP
					;
	CALL	ATAPI_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	IN	A,(IDECTRL)		; READ STATUS (FOR DELAY)
					;
	RET				;
	
;__SETUPDRIVE__________________________________________________________________________________________________________________________ 
;
;	SETUP FLOPPY DRIVE SETTINGS 
;________________________________________________________________________________________________________________________________
;
;
;
SETUPDRIVE:
	LD	A,RESETL		; RESET SETTINGS
	OR	MINI			; SELECT MINI FLOPPY (LOW DENS=1, HIGH DENS=0)
	OR	PRECOMP			; SELECT PRECOMP 
	OR	FDDENSITY		; SELECT DENSITY
	OR	FDREADY			; SELECT READY SIGNAL
	LD	(FLATCH_STORE),A	; SAVE SETTINGS
	LD	A,01H			;
	LD	(UNIT),A		; SET UNIT 1
	LD	A,2			; DENSITY
	LD	(DENS),A		;
	LD	A,09			;
	LD	(EOTSEC),A		; LAST SECTOR OF TRACK			
	LD	A,7FH			;
	LD	(SRTHUT),A		; STEP RATE AND HEAD UNLOAD TIME
	LD	A,05H			;
	LD	(HLT),A			; HEAD LOAD TIME
	LD	A,0DH			;
	LD	(GAP),A			; GAP 
	LD	A,80H			;
	LD	(SECSIZ),A		; SECTOR SIZE /4
					;
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
					;					
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	RES	1,(HL)			; SET MOTOR ON
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	NOP				;
	NOP				;
	LD	A,00H			; ZERO TRACK
	LD	(TRACK),A		; STORE TRACK
	CALL	SETTRACK		; DO IT	
	NOP				;
	NOP				;
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	1,(HL)			; SET MOTOR OFF
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	RET
;
;__OUTFLATCH__________________________________________________________________________________________________________________________ 
;
;	SEND SETTINGS TO FLOPPY CONTROLLER
;________________________________________________________________________________________________________________________________
;
OUTFLATCH:
	LD	A,(FLATCH_STORE)	; SET A TO SETTINGS
	OUT	(FLATCH),A		; OUTPUT TO CONTROLLER
	RET

		
;__FLOPPYREAD__________________________________________________________________________________________________________________________ 
;
; 	READ A FLOPPY DISK SECTOR 	
;________________________________________________________________________________________________________________________________
;	
FLOPPYREAD:
	.IF	USEDSKY
	CALL	SEGDISPLAY		;
	.ENDIF
	LD	A,46H			; BIT 6 SETS MFM, 06H IS READ COMMAND
	LD	(CMD),A			;
	JP	DSKOP			;
;
;__FLOPPYWRITE__________________________________________________________________________________________________________________________ 
;
; 	WRITE A FLOPPY DISK SECTOR 	
;________________________________________________________________________________________________________________________________
;	
FLOPPYWRITE:
	.IF	USEDSKY
	CALL	SEGDISPLAY		;
	.ENDIF
	LD	A,45H			; BIT 6 SETS MFM, 05H IS WRITE COMMAND
	LD	(CMD),A			;
	JP	DSKOP			;
;
;__DSKOP__________________________________________________________________________________________________________________________ 
;
; 	PERFORM A DISK OPERATION 	
;________________________________________________________________________________________________________________________________
;		
DSKOP:
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	1,(HL)			; SET MOTOR OFF
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
					;
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CP	0FFH			; DID IT RETURN WITH ERROR CODE?
	JP	Z,DSKEXIT		; IF YES, EXIT WITH ERROR CODE
					;	
	LD	A,(UNIT)		; GET DISK UNIT NUMBER
	AND	03H			; MASK FOR FOUR DRIVES 
	LD	B,A			; PARK IT IN B
	LD	A,(HEAD)		; GET HEAD SELECTION
	AND	01H			; INSURE SINGLE BIT
	RLA				;
	RLA				; MOVE HEAD TO BIT 2 POSITION
	OR	B			; OR HEAD TO UNIT BYTE IN COMMAND BLOCK
	LD	(UNIT),A		; STORE IN UNIT
					;
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	RES	1,(HL)			; SET MOTOR ON
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER	
					;
	LD	A,03H			; SPECIFY COMMAND
	CALL	PFDATA			; PUSH IT
	LD	A,(SRTHUT)		; STEP RATE AND HEAD UNLOAD TIME
	CALL	PFDATA			; PUSH THAT
	LD	A,(HLT)			;
	CALL	PFDATA			; PUSH THAT
					;
	CALL	SETTRACK		; PERFORM SEEK TO TRACK
					;
	JP	NZ,DSKEXIT		; IF ERROR, EXIT
					;
	LD	A,(CMD)			; WHAT COMMAND IS PENDING?
	OR	A			; SET FLAGS
	JP	DOSO4			; NO, MUST BE READ OR WRITE COMMAND
DSKEXIT:	
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	1,(HL)			; SET MOTOR OFF
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
					;
	OR	0FFH			; SET -1 IF ERROR
	RET

RESULT:
	LD	C,07H			; LOAD C WITH NUMBER OF STATUS BYTES
	LD	HL,ST0			; POINT TO STATS STORAGE
RS3:
	CALL	GFDATA			; GET FIRST BYTE
	LD	(HL),A			; SAVE IT
	INC	HL			; POINTER++
	DEC	C			; CC-1
	JP	NZ,RS3			; LOOP TIL C0
	LD	A,(ST0)			; LOAD STS0
	AND	0F8H			; MASK OFF DRIVE #
	LD	B,A			; PARK IT
	LD	A,(ST1)			; LOAD STS1
	OR	B			; ACC OR B ->ACC IF 0 THEN SUCCESS
					;
RSTEXIT:
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	1,(HL)			; SET MOTOR OFF
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
					;
	.IF	USEDSKY					
	CALL	SEGDISPLAY		;
	.ENDIF
	RET				; DONE RETURN TO CALLER 
	
	
DOSO4:
					;
	LD	HL,SECTOR_BUFFER	; GET BUFFER ADDRESS TO HL
	LD	A,(SECSIZ)		; XFERLEN
	LD	C,A			; C WILL BE THE NUMBER OF TRANSACTIONS
					; DIVIDED BY 4
					;
	LD	A,(CMD)			;
	CALL	PFDATA			; PUSH COMMAND TO I8272
	LD	A,(UNIT)		;
	CALL	PFDATA			; 
	LD	A,(TRACK)		;
	CALL	PFDATA			; 
	LD	A,(HEAD)		;
	CALL	PFDATA			; 
	LD	A,(SECTOR)		;
	INC	A			;
	CALL	PFDATA			; 
	LD	A,(DENS)		;
	CALL	PFDATA			; WHAT DENSITY
	LD	A,(EOTSEC)		;
	CALL	PFDATA			; ASSUME SC (SECTOR COUNT)  EOT
	LD	A,(GAP)			;
	CALL	PFDATA			; WHAT GAP IS NEEDED
	LD	A,(DTL)			; DTL, IS THE LAST COMMAND BYTE TO I8272
	CALL	PFDATAS
	LD	A,(CMD)			; READ IS 0 IS THIS A READ OR WRITE?
	AND	000000001b		; WRITE IS 1
	JP	NZ,WRR			; JMP WRITE IF 1
;

	;
; PERFORM READ
; LOOP EXECUTES 4X, THIS ALLOWS C RATHER THAN BC AS COUNTER
; SAVING A FEW TSTATES  MAKES UP TO 1024 BYTE SECTORS POSSIBLE.
; FROM READ TO READ MUST NOT EXCEED 25US WORST CASE MIN 
; (76T STATES FOR 3MHZ 8085) OR (100 T STATES FOR 4MHZ Z80)
;

RDD_POLL:
FDC_READP0:
	IN	A,(FMSR)		;
	OR	A			; TEST IF BYTE READY RQM1
	JP	P,FDC_READP0		;	
					;
	AND	20H			;
	JP	Z,DSKOPEND		;JUMP IF IN RESULTS MODE
					;
	IN	A,(FDATA)		;
	LD	(HL),A			;
	INC	HL			;

FDC_READP1:
	IN	A,(FMSR)		;
	OR	A			;
	JP	P,FDC_READP1		;
					;
	AND	20H			;
	JP	Z,DSKOPEND		;
					;
	IN	A,(FDATA)		;
	LD	(HL),A			;
	INC	HL			;
					;
FDC_READP2:
	IN	A,(FMSR)		;
	OR	A			;
	JP	P,FDC_READP2		;
					;
	AND	20H			;
	JP	Z,DSKOPEND		;
					;
	IN	A,(FDATA)		;
	LD	(HL),A			;
	INC	HL			;
					;
FDC_READP3:
	IN	A,(FMSR)		; 11
	OR	A			; 4
	JP	P,FDC_READP3		; 10
					;
	AND	20H			; 7
	JP	Z,DSKOPEND		; 10
					;
	IN	A,(FDATA)		; 11
	LD	(HL),A			; 10
	INC	HL			; 11
					;
	DEC	C			; 4
	JP	NZ,FDC_READP0		; 11

DSKOPEND:
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	0,(HL)			; SET TC
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	NOP				;
	NOP				; 2 MICROSECOND DELAY
	RES	0,(HL)			; RESET TC
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	NOP				;
	NOP				; 2 MICROSECOND DELAY
	NOP				;
	NOP				; 2 MICROSECOND DELAY
	SET	1,(HL)			; TURN OFF MOTOR
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	JP	RESULT			; GET STATUS BYTES <RESULT PHASE>
WRR:
FDC_WRITEP0:
	IN	A,(FMSR)		;
	OR	A			; TEST IF BYTE READY RQM1
	JP	P,FDC_WRITEP0		;	
					;
	AND	20H			;
	JP	Z,DSKOPEND		;JUMP IF IN RESULTS MODE
					;
	LD	A,(HL)			;
	OUT	(FDATA),A		;	
	INC	HL			;

FDC_WRITEP1:
	IN	A,(FMSR)		;
	OR	A			;
	JP	P,FDC_WRITEP1		;
					;
	AND	20H			;
	JP	Z,DSKOPEND		;
					;
	LD	A,(HL)			;
	OUT	(FDATA),A		;	
	INC	HL			;
					;
FDC_WRITEP2:
	IN	A,(FMSR)		;
	OR	A			;
	JP	P,FDC_WRITEP2		;
					;
	AND	20H			;
	JP	Z,DSKOPEND		;
					;
	LD	A,(HL)			;
	OUT	(FDATA),A		;	
	INC	HL			;
					;
FDC_WRITEP3:
	IN	A,(FMSR)		; 11
	OR	A			; 4
	JP	P,FDC_WRITEP3		; 10
					;
	AND	20H			; 7
	JP	Z,DSKOPEND		; 10
					;
	LD	A,(HL)			;
	OUT	(FDATA),A		;	
	INC	HL			; 11
					;
	DEC	C			; 4
	JP	NZ,FDC_WRITEP0		; 11
	JP	DSKOPEND		; 10
	
		
;__SETTRACK__________________________________________________________________________________________________________________________ 
;
; 	SEEK TO A TRACK ON GIVEN UNIT
; 	A: TRACK #
;________________________________________________________________________________________________________________________________
;
SETTRACK:
	LD	A,(TRACK)		; GET TRACK
	OR	A			; SET FLAGS
	JP	Z,RECAL			; IF 0 PERFORM RECAL INSTEAD OF SEEK
	LD	(TRACK),A		; STORE TRACK
	LD	A,0FH			; SEEK COMMAND
	CALL	PFDATA			; PUSH COMMAND
	LD	A,(UNIT)		; SAY WHICH UNIT
	CALL	PFDATA			; SEND THAT
	LD	A,(TRACK)		; TO WHAT TRACK
	CALL	PFDATA			; SEND THAT TOO
	JP	WAINT			; WAIT FOR INTERRUPT SAYING DONE
RECAL:
	LD	A,00H			;
	LD	(TRACK),A		; STORE TRACK
	LD	A,07H			; RECAL TO TRACK 0
	CALL	PFDATA			; SEND IT
	LD	A,(UNIT)		; WHICH UNIT
	CALL	PFDATA			; SEND THAT TOO
;
WAINT:
;
	CALL	DELAYHSEC		; DELAY TO LET HEADS SETTLE BEFORE READ
					;
					; WAIT HERE FOR INTERRPT SAYING DONE
					; LOOP TIL INTERRUPT
	CALL	CHECKINT		; CHECK INTERRUPT STATUS
;
	RET
	
;__PFDATAS__________________________________________________________________________________________________________________________ 
;
; WRITE A COMMAND OR PARAMETER S EQUENCE
;
; TRANSFERS ARE SYNCHONIZED BYT MSR D7 <RQM> AND D6 <DIO>
;	RQM  DIO
;	0	0	BUSY
;	1	0	WRITE TO DATA REGISTER PERMITTED
;	1	1	BYTE FOR READ BY HOST PENDING
;	0	1	BUSY
;
;________________________________________________________________________________________________________________________________
;
PFDATAS:
	PUSH	AF			; STORE AF
PFDS1:
	IN	A,(FMSR)		; READING OR WRITING IS KEYS TO D7 RQM
	AND	80H			; MASK OFF RQM BIT 
	JP	Z,PFDS1			; WAIT FOR RQM TO BE TRUE 
	IN	A,(FMSR)		; READ STATUS
	AND	40H			; WAITING FOR INPUT?
	CALL	NZ,ERRORT		; NO, SIGNAL ERROR
	POP	AF			; RESTORE AF
	OUT	(FDATA),A		; OUTPUT A TO CONTROLLER
	RET		
	
;__PFDATA__________________________________________________________________________________________________________________________ 
;
; WRITE A COMMAND OR PARAMETER S EQUENCE
;
; TRANSFERS ARE SYNCHONIZED BYT MSR D7 <RQM> AND D6 <DIO>
;	RQM  DIO
;	0	0	BUSY
;	1	0	WRITE TO DATA REGISTER PERMITTED
;	1	1	BYTE FOR READ BY HOST PENDING
;	0	1	BUSY
;
;________________________________________________________________________________________________________________________________
;
PFDATA:
	PUSH	AF			; STORE AF
PFD1:
	IN	A,(FMSR)		; READING OR WRITING IS KEYS TO D7 RQM
	AND	80H			; MASK OFF RQM BIT 
	JP	Z,PFD1			; WAIT FOR RQM TO BE TRUE 
	IN	A,(FMSR)		; READ STATUS
	AND	40H			; WAITING FOR INPUT?
	CALL	NZ,ERRORT		; NO, SIGNAL ERROR
	POP	AF			; RESTORE AF
	OUT	(FDATA),A		; OUTPUT A TO CONTROLLER
	JP	DELAY24			; DELAY 24US
	
	
	
;__DELAY24__________________________________________________________________________________________________________________________ 
;
; 	DELAY 24US
;________________________________________________________________________________________________________________________________
;
	
DELAY24:	
					; JP= 10T	
	PUSH	IX			; 15T
	POP	IX			; 14T
	PUSH	IX			; 15T
	POP	IX			; 14T
DELAY12:
	PUSH	IX			; 15T
	POP	IX			; 14T
	RET				; 10T


;__CHECKINT__________________________________________________________________________________________________________________________ 
;
; CHECK FOR ACTIVE FDC INTERRUPTS BEFORE GIVING I8272 COMMANDS
; POLL RQM FOR WHEN NOT BUSY AND THEN SEND FDC
; SENSE INTERRUPT COMMAND   IF IT RETURNS WITH NON ZERO
; ERROR CODE, PASS BACK TO CALLING ROUTINE FOR HANDLING
;________________________________________________________________________________________________________________________________
;
CHECKINT:
	IN	A,(FMSR)		; READING OR WRITING IS KEYS TO D7 RQM
	AND	80H			; MASK OFF RQM BIT
	JP	Z,CHECKINT		; WAIT FOR RQM TO BE TRUE  WAIT UNTIL DONE
	IN	A,(FMSR)		; READ STATUS
	AND	40H			; WAITING FOR INPUT?
	JP	NZ,CHECKINTDONE		; NO, SIGNAL ERROR
	CALL	SENDINT			; SENSE INTERRUPT COMMAND
CHECKINTDONE:
	RET				;
	

;__DELAYHSEC__________________________________________________________________________________________________________________________ 
;
; DELAY FOR 1/2 SECOND
;________________________________________________________________________________________________________________________________
;		
DELAYHSEC:
	LD	HL,00000H		; 65536
DELDM:
	NOP				; (4 T) 
	NOP				; (4 T)
	NOP				; (4 T)
	NOP				; (4 T)
	DEC	L			; (6 T)
	JP	NZ,DELDM		; (10 T) 24 T  8 MICROSECONDS AT 4 MHZ
	DEC	H			; (6 T)
	JP	NZ,DELDM		; (10 T) (8 US * 256) * 256  524288 US   5 SECONDS
	RET

;__ERRORT__________________________________________________________________________________________________________________________ 
;
; ERROR HANDLING
;________________________________________________________________________________________________________________________________
;			
ERRORT:
	IN	A,(FDATA)		; CLEAR THE JUNK OUT OF DATA REGISTER
	IN	A,(FMSR)		; CHECK WITH RQM
	AND	80H			; IF STILL NOT READY, READ OUT MORE JUNK
	JP	Z,ERRORT		;
	LD	A,0FFH			; RETURN ERROR CODE -1
					;
	RET
;__SENDINT__________________________________________________________________________________________________________________________ 
;
; SENSE INTERRUPT COMMAND
;________________________________________________________________________________________________________________________________
;			
SENDINT:
	LD	A,08H			; SENSE INTERRUPT COMMAND
	CALL	PFDATA			; SEND IT
	CALL	GFDATA			; GET RESULTS
	LD	(ST0A),A		; STORE THAT
	AND	0C0H			; MASK OFF INTERRUPT STATUS BITS
	CP	80H			; CHECK IF INVALID COMMAND
	JP	Z,ENDSENDINT		; YES, EXIT
	CALL	GFDATA			; GET ANOTHER (STATUS CODE 1)
	LD	(ST1A),A		; SAVE THAT
	LD	A,(ST0A)		; GET FIRST ONE
	AND	0C0H			; MASK OFF ALL BUT INTERRUPT CODE 00 IS NORMAL
ENDSENDINT:
	RET				;ANYTHING ELSE IS AN ERROR


;__GFDATA__________________________________________________________________________________________________________________________ 
;
; GET DATA FROM FLOPPY CONTROLLER
;
; TRANSFERS ARE SYNCHONIZED BYT MSR D7 <RQM> AND D6 <DIO>
;	RQM  DIO
;	0	0	BUSY
;	1	0	WRITE TO DATA REGISTER PERMITTED
;	1	1	BYTE FOR READ BY HOST PENDING
;	0	1	BUSY
;
;________________________________________________________________________________________________________________________________
;		
GFDATA:
	IN	A,(FMSR)		; READ STATUS BYTE
	AND	80H			; MASK OFF RQM
	JP	Z,GFDATA		; LOOP WHILE BUSY
	IN	A,(FMSR)		; READ STSTUS BUTE
	AND	40H			; MASK OFF DIO
	CALL	Z,ERRORT		; IF WRITE EXPECTED RUN ERRORRT
	IN	A,(FDATA)		; READ DATA
	JP	DELAY24			; DELAY 24US
	

; PIO 82C55 I/O IS DECODED TO PORT 60-67
;
PORTA		 .EQU 	60H
PORTB		 .EQU 	61H
PORTC		 .EQU 	62H
PIOCONT 	 .EQU 	63H	

;__IDESEGDISPLAY________________________________________________________________________________________
;
;  DISPLAY CONTENTS OF IDE LOGICAL BLOCK ADDRESS ON DSKY    
;____________________________________________________________________________________________________
IDESEGDISPLAY:
	LD	A, 82H			;
	OUT (PIOCONT),A			;
					;
	LD	A,(IDE_LBA3)		;
	AND	0FH			;
	LD	(DISPLAYBUF+6),A	;
	LD	A,(IDE_LBA3)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+7),A	;
					;
	LD	A,(IDE_LBA2)		;
	AND	0FH			;
	LD	(DISPLAYBUF+4),A	;
	LD	A,(IDE_LBA2)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+5),A	;
					;
	LD	A,(IDE_LBA1)		;
	AND	0FH			;
	LD	(DISPLAYBUF+2),A	;
	LD	A,(IDE_LBA1)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+3),A	;
	
	LD	A,(IDE_LBA0)		;
	AND	0FH			;
	LD	(DISPLAYBUF),A		;
	LD	A,(IDE_LBA0)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+1),A	;
	JP	SEGDISPLAY1		;
;__ATAPISEGDISPLAY________________________________________________________________________________________
;
;  DISPLAY CONTENTS OF ATAPI LOGICAL BLOCK ADDRESS ON DSKY    
;____________________________________________________________________________________________________
ATAPISEGDISPLAY:
	LD	A, 82H			;
	OUT (PIOCONT),A			;
					;
	LD	A,(LBA_TARGET_HI+1)	;
	AND	0FH			;
	LD	(DISPLAYBUF+6),A	;
	LD	A,(LBA_TARGET_HI+1)	;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+7),A	;
					;
	LD	A,(LBA_TARGET_HI)	;
	AND	0FH			;
	LD	(DISPLAYBUF+4),A	;
	LD	A,(LBA_TARGET_HI)	;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+5),A	;
					;
	LD	A,(LBA_TARGET_LO+1)	;
	AND	0FH			;
	LD	(DISPLAYBUF+2),A	;
	LD	A,(LBA_TARGET_LO+1)	;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+3),A	;
	
	LD	A,(LBA_TARGET_LO)	;
	AND	0FH			;
	LD	(DISPLAYBUF),A		;
	LD	A,(LBA_TARGET_LO)	;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+1),A	;
	JP	SEGDISPLAY1		;

;__SEGDISPLAY________________________________________________________________________________________
;
;  DISPLAY CONTENTS OF TRACK, SECTOR, ST0, ST1 ON DSKY
;     
;____________________________________________________________________________________________________
SEGDISPLAY:
	LD	A, 82H			;
	OUT (PIOCONT),A			;
	LD	A,(TRACK)		;
	AND	0FH			;
	LD	(DISPLAYBUF+6),A	;
	LD	A,(TRACK)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+7),A	;			
	LD	A,(SECTOR)		;
	AND	0FH			;
	LD	(DISPLAYBUF+4),A	;
	LD	A,(SECTOR)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+5),A	;
	LD	A,(ST0)			;
	AND	0FH			;
	LD	(DISPLAYBUF+2),A	;
	LD	A,(ST0)			;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+3),A	;			
	LD	A,(ST1)			;
	AND	0FH			;
	LD	(DISPLAYBUF),A		;
	LD	A,(ST1)			;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+1),A	;
SEGDISPLAY1:				;
	LD	HL,DISPLAYBUF		;
	LD	BC,0007H		;
	ADD	HL,BC			;
	LD	B,08H			; SET DIGIT COUNT
	LD	A,40H			; SET CONTROL PORT 7218 TO OFF
	OUT	(PORTC),A		; OUTPUT
	CALL 	DELAY12			; WAIT
	LD	A,0D0H			; SET CONTROL TO 1111 (DATA COMING, HEX DECODE, DECODE, NORMAL)
	OUT	(PORTA),A		; OUTPUT TO PORT
	LD	A,80H			; STROBE WRITE PULSE WITH CONTROL=1
	OUT	(PORTC),A		; OUTPUT TO PORT
	CALL 	DELAY12			; WAIT
	LD	A,40H			; SET CONTROL PORT 7218 TO OFF
	OUT	(PORTC),A		; OUTPUT
	CALL 	DELAY12			; WAIT
SEGDISPLAY_LP:		
	LD	A,(HL)			; GET DISPLAY DIGIT
	OUT	(PORTA),A		; OUT TO PORTA
	LD	A,00H			; SET WRITE STROBE
	OUT	(PORTC),A		; OUT TO PORTC
	CALL	DELAY12			; DELAY
	LD	A,40H			; SET CONTROL PORT OFF
	OUT	(PORTC),A		; OUT TO PORTC
	CALL	DELAY12			; WAIT
	DEC	HL			; INC POINTER
	DJNZ	SEGDISPLAY_LP		; LOOP FOR NEXT DIGIT
	RET	
	
DISPLAYBUF:	 .DB 	01,02,03,04,05,06,07,08
		 .DB	00,00,00,00,00,00,00,00	
		 .DB	00,00,00,00,00,00,00,00	
		 .DB	00,00,00,00,00,00,00,00	
		 .DB	00,00,00,00,00,00,00,00	
FLOPPYSTACK:	 .DB	00
PARKSTACK:	 .DB	00,00,00,00
		
READ_DISK_PACKET
		 .DB	0A8H,00,00,00,00,01H,00,00,00,01H,00,00
WRITE_DISK_PACKET
		 .DB	2AH,00,00,00,00,11H,00,00,01H,00,00,00
ATAPI_REQUEST_SENSE
		 .DB	03H,00,00,00,011H,00,00,00,00,00,00,00

;
; DISK COMMAND BLOCK
;
CMD:		 .DB	0			; COMMAND READ OR WRITE,
UNIT:		 .DB	0			; PHYSICAL DRIVE 0->3
DENS:		 .DB	2			; DENSITY
EOTSEC:		 .DB	09			; LAST SECTOR OF TRACK
GAP:		 .DB	1BH			; VALUE FOR IRG <GAP3>
SECSIZ:		 .DB	080H			; HOW MANY BYTES TO TRANSFER/4
DTL:		 .DB	0FFH			; SIZE OF SECTOR
SRTHUT:		 .DB	7FH			; STEP RATE AND HEAD UNLOAD TIME
HLT:		 .DB	05H			; HEAD LOAD TIME
MIN:		 .DB	MINI			; LATCH BIT PATTERN FOR FDC9229 MINITRUE
PRE:		 .DB	PRECOMP			; LATCH BIT PATTERN FOR FDC9229 PRECOMP125NS
;
; FLOPPY STATUS RESULT STORAGE
;
ST0:		.DB	0			; STORE STATUS 0
ST1:		.DB	0			; ST1
ST2:		.DB	0			; ST2
SCYL:		.DB	0			; TRACK
SHEAD:		.DB	0			; HEAD 0 OR 1
SREC:		.DB	0			; SECTOR
SNBIT:		.DB	0			; DENSITY
ST0A:		.DB	0			; STORE STATUS 0
ST1A:		.DB	0			; ST1
RETRY		.DB	0			; RETRIES
RETRY1		.DB	0			; RETRIES

FLATCH_STORE:	.DB	00

CPMSTART	.DW	00			; START OF CP/M
DRIVE		.DB	0			; DRIVE
TRACK		.DB 	0			; TRACK
HEAD		.DB	0			; HEAD
SECTOR		.DB	0			; SECTOR
LBA_TARGET_LO:	.DW 	0			; IDE HD PARTITION TARGET SECTOR (LOW 16 BITS)
LBA_TARGET_HI:	.DW 	0			; IDE HD PARTITION TARGET SECTOR (HI 16 BITS, 12 USED)
IDEDEVICE:	.DB 	0			; ATAPI DEVICE SELECTION FLAG

IDE_LBA0:	.DB 	0			; SET LBA 0:7
IDE_LBA1:	.DB 	0			; SET LBA 8:15
IDE_LBA2:	.DB 	0			; SET LBA 16:23
IDE_LBA3:	.DB 	0			; LOWEST 4 BITS USED ONLY TO ENABLE LBA MODE 
;
	
;__HXOUT_________________________________________________________________________________________________________________________ 
;
;	PRINT THE ACCUMULATOR CONTENTS AS HEX DATA ON THE SERIAL PORT
;________________________________________________________________________________________________________________________________
;
HXOUT:
	PUSH	BC			; SAVE BC
	LD	B,A			;
	RLC	A			; DO HIGH NIBBLE FIRST  
	RLC	A			;
	RLC	A			;
	RLC	A			;
	AND	0FH			; ONLY THIS NOW
	ADD	A,30H			; TRY A NUMBER
	CP	3AH			; TEST IT
	JR	C,OUT1			; IF CY SET PRINT 'NUMBER'
	ADD	A,07H			; MAKE IT AN ALPHA
OUT1:
	CALL	COUT			; SCREEN IT
	LD	A,B			; NEXT NIBBLE
	AND	0FH			; JUST THIS
	ADD	A,30H			; TRY A NUMBER
	CP	3AH			; TEST IT
	JR	C,OUT2			; PRINT 'NUMBER'
	ADD	A,07H			; MAKE IT ALPHA
OUT2:
	CALL	COUT			; SCREEN IT
	POP	BC			; RESTORE BC
	RET				;


;__SPACE_________________________________________________________________________________________________________________________ 
;
;	PRINT A SPACE CHARACTER ON THE SERIAL PORT
;________________________________________________________________________________________________________________________________
;
SPACE:
	PUSH	AF			; Store AF
	LD	A,20H			; LOAD A "SPACE"
	CALL	COUT			; SCREEN IT
	POP	AF			; RESTORE AF
	RET				; DONE

;__CRLF_________________________________________________________________________________________________________________________ 
;
;	PRINT A cr/lf
;________________________________________________________________________________________________________________________________
;
CRLF:
	PUSH	AF			; Store AF
	LD	A,0DH			; LOAD A "SPACE"
	CALL	COUT			; SCREEN IT
	LD	A,0AH			; LOAD A "SPACE"
	CALL	COUT			; SCREEN IT
	POP	AF			; RESTORE AF
	RET				; DONE

;__COUT_________________________________________________________________________________________________________________________ 
;
;	PRINT CONTENTS OF A 
;________________________________________________________________________________________________________________________________
;
COUT:
	PUSH	BC			;
	PUSH	AF			;
	PUSH	HL			;
	PUSH	DE			;
		
	LD	(COUT_BUFFER),A		;
	LD	DE,COUT_BUFFER		;
	LD	C,09H			; CP/M WRITE START STRING TO CONSOLE CALL
	CALL	0005H
	POP	DE			;
	POP	HL			;
	POP	AF			;
	POP	BC			;
	RET				; DONE




;__PHL_________________________________________________________________________________________________________________________ 
;
;	PRINT THE HL REG ON THE SERIAL PORT
;________________________________________________________________________________________________________________________________
;
PHL:
	LD	A,H			; GET HI BYTE
	CALL	HXOUT			; DO HEX OUT ROUTINE
	LD	A,L			; GET LOW BYTE
	CALL	HXOUT			; HEX IT
	CALL	SPACE			; 
	RET				; DONE  

COUT_BUFFER:
	.DB	00
	.DB	"$"


SECTOR_BUFFER:	.DS 520				; STORAGE BUFFER
	
	
	.end
	